﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace MDT.LifeSewagePlatform.Conmmon
{
    public class BaseController : ControllerBase
    {
        private JsonWebTokenEntity Config_TokenParameter { get; set; }

        [Autowired]
        protected IOptions<JsonWebTokenEntity> _options { get; set; }
        public BaseController()
        {
        }
        protected int GetUserID()
        {
            string UserID = HttpContext.User.Claims.Where(c => c.Type == ClaimTypes.NameIdentifier).FirstOrDefault().Value;
            if (!string.IsNullOrEmpty(UserID))
            {
                return int.Parse(UserID);
            }
            return -1;
        }
        protected int GetCompanyID()
        {
            string CompanyID = HttpContext.User.Claims.Where(c => c.Type.Contains("CompanyID")).FirstOrDefault().Value;
            if (!string.IsNullOrEmpty(CompanyID))
            {
                return int.Parse(CompanyID);
            }
            return -1;
        }

        protected string GetRoleName()
        {
            string RoleName = HttpContext.User.Claims.Where(c => c.Type.Contains("RoleName")).FirstOrDefault().Value;
            return RoleName;
        }
        protected string GetPlaceTypeName()
        {
            string PlaceTypeName = HttpContext.User.Claims.Where(c => c.Type == "PlaceTypeName").FirstOrDefault().Value;

            return PlaceTypeName;
        }

        protected int GetPlaceTypeID()
        {
            string PlaceTypeID = HttpContext.User.Claims.Where(c => c.Type == "PlaceTypeID").FirstOrDefault().Value;

            if (!string.IsNullOrEmpty(PlaceTypeID))
            {
                return int.Parse(PlaceTypeID);
            }
            return -1;
        }

        protected int GetCurrentAreaID()
        {
            string CurrentAreaID = HttpContext.User.Claims.Where(c => c.Type == "CurrentAreaID").FirstOrDefault().Value;

            if (!string.IsNullOrEmpty(CurrentAreaID))
            {
                return int.Parse(CurrentAreaID);
            }
            return -1;
        }

        protected int GetRoleID()
        {
            string RoleID = HttpContext.User.Claims.Where(c => c.Type == "RoleID").FirstOrDefault().Value;

            if (!string.IsNullOrEmpty(RoleID))
            {
                return int.Parse(RoleID);
            }
            return -1;
        }

        protected int GetRoleValue()
        {
            string RoleVale = HttpContext.User.Claims.Where(c => c.Type == ClaimTypes.Role).FirstOrDefault().Value;

            if (!string.IsNullOrEmpty(RoleVale))
            {
                return int.Parse(RoleVale);
            }
            return -1;
        }

        protected CurrentUserInfo CurrentUserInfo()
        {
            return new CurrentUserInfo()
            {
                CurrentAreaID = GetCurrentAreaID(),
                UserID = GetUserID(),
                CompanyID = GetCompanyID(),
                PlaceTypeID = GetPlaceTypeID(),
                RoleID = GetRoleID(),
                PlaceTypeName = GetPlaceTypeName(),
                RoleName = GetRoleName(),
                RoleValue = GetRoleValue(),
            };
        }

        protected bool IsAdmin()
        {
            if (GetRoleID() == (int)eRoleType.Admin)
            {
                return true;
            }
            return false;
        }

        protected async Task<string> GetToken(CurrentUserInfo user)
        {
            return await Task.Run<string>(() =>
             {
                 if (Config_TokenParameter == null)
                 {
                     Config_TokenParameter = _options.Value;
                 }
                 var claims = new[]
                              {
                new Claim (ClaimTypes.NameIdentifier,user.UserID.ToString()),
                new Claim (ClaimTypes.Role,user.RoleValue.ToString()),
                new Claim ("RoleName",user.RoleName),
                new Claim ("CompanyID",user.CompanyID.ToString()),
                new Claim ("PlaceTypeID",user.PlaceTypeID.ToString()),
                new Claim ("PlaceTypeName",user.PlaceTypeName),
                new Claim ("RoleID",user.RoleID.ToString()),
                new Claim ("CurrentAreaID",user.CurrentAreaID.ToString()),
             };
                 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Config_TokenParameter.Secret));
                 var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                 var jwtToken = new JwtSecurityToken(Config_TokenParameter.Issuer, Config_TokenParameter.Audience,
                     claims, expires: DateTime.UtcNow.AddMinutes(Config_TokenParameter.AccessExpiration), signingCredentials: credentials);
                 var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
                 return token;
             });
        }

        protected IActionResult Bad400(string msg)
        {
            return Ok(new { code = 400, msg = msg, status = false });
        }

        protected IActionResult Ok200(string msg)
        {
            return Ok(new { code = 200, msg = msg, status = true });
        }

        protected IActionResult Ok200(object data, string msg)
        {
            return Ok(new { code = 200, msg = msg, data = data, status = true });
        }

        protected IActionResult Ok200(object data, string msg, int total)
        {
            return Ok(new { code = 200, msg = msg, data = data, status = true, total = total });
        }
        protected IActionResult Ok200(object data, string msg, int total, int PageSize, int PageCurrent)
        {
            return Ok(new { code = 200, msg = msg, data = data, status = true, total = total, pagesize = PageSize, pagecurrent = PageCurrent });
        }

        protected IActionResult Ok200<T>(string msg, PageList<T> data)
        {
            return Ok(new { code = 200, msg = msg, data = data, status = true, total = data.TotalCount, pagesize = data.PageSize, pagecurrent = data.CurrentPage });
        }

        protected async Task SaveFile(List<IFormFile> files, string dic, Func<string, bool> func, bool IsRandomName = true)
        {
            if (System.IO.Directory.Exists(dic) == false)
            {
                System.IO.Directory.CreateDirectory(dic);
            }
            foreach (var file in files)
            {
                string extension = Path.GetExtension(file.FileName);

                if (func != null && func.Invoke(extension))
                {
                    string randomName = IsRandomName ? Path.GetRandomFileName() : file.FileName;

                    string outfile = Path.GetFileNameWithoutExtension(randomName) + extension;

                    var filePath = string.Empty;
                    if (randomName.Contains("\\"))
                    {
                        filePath = Path.Combine(dic,Path.GetDirectoryName(file.FileName));
                        if (Directory.Exists(filePath)==false)
                        {
                            Directory.CreateDirectory(filePath);
                        }
                        filePath=Path.Combine(filePath,outfile);
                    }
                    else
                    {
                        filePath = Path.Combine(dic, outfile);
                    }

                    Path.Combine(dic, outfile);

                    if (System.IO.File.Exists(filePath))
                    {
                        System.IO.File.Delete(filePath);
                    }
                    using (var stream = System.IO.File.Create(filePath))
                    {
                        await file.CopyToAsync(stream);
                    }
                }
            }
        }

        protected async Task SaveFile(IFormFile file, string dic, string fileName, Func<string, bool> func)
        {
            string extension = Path.GetExtension(file.FileName);
            if (func != null && func.Invoke(extension) == false)
            {
                return;
            }
            if (System.IO.Directory.Exists(dic) == false)
            {
                System.IO.Directory.CreateDirectory(dic);
            }
            if (string.IsNullOrEmpty(fileName))
            {
                fileName = Path.GetRandomFileName();
            }
            string outfile = Path.GetFileNameWithoutExtension(fileName) + extension;
            var filePath = Path.Combine(dic, outfile);

            if (System.IO.File.Exists(filePath))
            {
                return;
            }
            using (var stream = System.IO.File.Create(filePath))
            {
                await file.CopyToAsync(stream);
            }
        }
        protected FileStream GetFile(string filePath)
        {
            FileStream fileStream = null;
            if (System.IO.File.Exists(filePath))
            {
                string FileName = System.IO.Path.GetFileName(filePath);
                fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                return fileStream;
            }
            return fileStream;
        }
    }
}
